package myservice.android.activities;

import java.io.File;
import java.util.Calendar;

import myservice.android.Global;
import myservice.android.R;
import myservice.android.database.Database;
import myservice.android.utilities.CalendarView;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;
import android.widget.ViewFlipper;

public class CalendarActivity extends Activity {
	
	private Button interestedButton;
	private Button settingsButton;
	private Button publicationsButton;
	private Button timerButton;
	private Button territoriesButton;
	private Button reportsButton;
	private Button previousMonthButton, nextMonthButton;
	private TextView windowTitle;	
	private TextView currentMonthText;
	private CalendarView[] calendarView = new CalendarView[2];
	private ViewFlipper viewFlipper;
	
	private TextView[] dayLabels = new TextView[7];
	private Calendar calendar; // selected date
	private Calendar today; // always points to today
	private float lastX; // previous touch X position to detect the direction in which to swipe the calendar
	private int activeCalendarView = 0; // index of "calendarView" currently being active on screen
	
    @Override
    public void onCreate(Bundle savedInstanceState) {    	
        super.onCreate(savedInstanceState);
        
        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
        setContentView(R.layout.calendar);
        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.titlebar);
        windowTitle = (TextView) findViewById(R.id.titleText);
        
        // Create "MyService" folder on SD card if possible
        createMyServiceFolder();
            	
    	Global.res = getResources();
    	Database.context=this;
        Database.openConnection();        
    	Global.loadSettings();    	
    	
    	Global.monthNames=Global.res.getStringArray(R.array.array_month_names);    	
    	Global.monthNamesShort=Global.res.getStringArray(R.array.array_month_names_short);     	
                
        windowTitle.setText(Global.res.getString(R.string.app_name));        
        
        interestedButton = (Button) findViewById(R.id.interestedButton);        
        settingsButton = (Button) findViewById(R.id.settingsButton);
        publicationsButton = (Button) findViewById(R.id.publicationsButton);
        timerButton = (Button) findViewById(R.id.timerButton);
        reportsButton = (Button) findViewById(R.id.reportsButton);
        territoriesButton = (Button) findViewById(R.id.territoriesButton);
        currentMonthText = (TextView) findViewById(R.id.selectedMonth);
        previousMonthButton = (Button) findViewById(R.id.previousButton);
        nextMonthButton = (Button) findViewById(R.id.nextButton); 
        viewFlipper = (ViewFlipper) findViewById(R.id.viewFlipper);
        calendarView[0] = (CalendarView) viewFlipper.findViewById(R.id.calendarView1);
        calendarView[1] = (CalendarView) viewFlipper.findViewById(R.id.calendarView2);
        
        // Retrieve day names above week days
        dayLabels[0] = (TextView) findViewById(R.id.dayLabel0);
        dayLabels[1] = (TextView) findViewById(R.id.dayLabel1);
        dayLabels[2] = (TextView) findViewById(R.id.dayLabel2);
        dayLabels[3] = (TextView) findViewById(R.id.dayLabel3);
        dayLabels[4] = (TextView) findViewById(R.id.dayLabel4);
        dayLabels[5] = (TextView) findViewById(R.id.dayLabel5);
        dayLabels[6] = (TextView) findViewById(R.id.dayLabel6);            
        
        today = Calendar.getInstance(); // Always points to today
        calendar = Calendar.getInstance(); // Initially points to today, but can be changed                  
        
        currentMonthText.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {												
				calendar.set(Calendar.YEAR, today.get(Calendar.YEAR));
				calendar.set(Calendar.MONTH, today.get(Calendar.MONTH));				
				loadMonth();				
			}        	
        });
        
        interestedButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View button) {
				Intent i = new Intent(getApplicationContext(), PersonListActivity.class);
				i.putExtra("mode",0); //Indicates that the user wants modify to interested persons, not pick a person from the list			
				startActivity(i);
			}        	
        });
        
        territoriesButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View button) {
				Intent i = new Intent(getApplicationContext(), TerritoryListActivity.class);
				i.putExtra("mode",0); //Indicates that the user wants modify territories, not pick a territory from the list			
				startActivity(i);
			}        	
        });        
        
        publicationsButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View button) {
				Intent i = new Intent(getApplicationContext(), PublicationListActivity.class);
				i.putExtra("person_id",0); //Indicates that owned publications should not be displayed			
				startActivity(i);
			}        	
        });   
        
        reportsButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View button) {
				Intent i = new Intent(getApplicationContext(), ReportsActivity.class);
				i.putExtra("month", calendar.get(Calendar.MONTH));
				i.putExtra("year", calendar.get(Calendar.YEAR));
				startActivity(i);
			}        	
        });        
        
        timerButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View button) {
				Intent i = new Intent(getApplicationContext(), TimerActivity.class);			
				startActivity(i);
			}        	
        });        
        
        settingsButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View button) {
				 Intent i = new Intent(getApplicationContext(),SettingsActivity.class);
			     startActivity(i);
			}        	
        });        
		
		previousMonthButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				switchMonth(-1);				
			}			
		});
		
		nextMonthButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				switchMonth(1);				
			}			
		});		
		
        // Tooltips
        interestedButton.setOnLongClickListener(new OnLongClickListener() {
			@Override
			public boolean onLongClick(View button) {
				Global.displayToast(CalendarActivity.this, Global.res.getString(R.string.tip_manage_persons));
				return true;
			}        	
        });
        
        settingsButton.setOnLongClickListener(new OnLongClickListener() {
			@Override
			public boolean onLongClick(View button) {
				Global.displayToast(CalendarActivity.this, Global.res.getString(R.string.tip_settings));
				return true;
			}        	
        }); 
        
        publicationsButton.setOnLongClickListener(new OnLongClickListener() {
			@Override
			public boolean onLongClick(View button) {
				Global.displayToast(CalendarActivity.this, Global.res.getString(R.string.tip_manage_publications));
				return true;
			}        	
        });  
        
        timerButton.setOnLongClickListener(new OnLongClickListener() {
			@Override
			public boolean onLongClick(View button) {
				Global.displayToast(CalendarActivity.this, Global.res.getString(R.string.tip_timer));
				return true;
			}        	
        }); 
        
        territoriesButton.setOnLongClickListener(new OnLongClickListener() {
			@Override
			public boolean onLongClick(View button) {
				Global.displayToast(CalendarActivity.this, Global.res.getString(R.string.tip_manage_territories));
				return true;
			}        	
        });    
        
        reportsButton.setOnLongClickListener(new OnLongClickListener() {
			@Override
			public boolean onLongClick(View button) {
				Global.displayToast(CalendarActivity.this, Global.res.getString(R.string.tip_reports));
				return true;
			}        	
        });  
        
    	// Check if database needs to be backed up to SD card (if SD card exists)
    	if (Global.autoBackupData && Global.folderMyServiceExists) {
    		if (Database.checkDatabaseBackup())
    			Global.displayToast(this, Global.res.getString(R.string.message_data_backed_up));
    	}        
        
    }
    
    private void loadMonth() {
    	
		final int month = calendar.get(Calendar.MONTH);
		final int year = calendar.get(Calendar.YEAR);
    	
        currentMonthText.setText(Global.monthNames[month]+" "+year);    		    	
    	
    	// Create listeners for buttons
		for (int i=0; i<6; i++) {
			for (int j=0; j<7; j++) {
				
				calendarView[activeCalendarView].calendarDays[i][j].setOnTouchListener(new OnTouchListener() {

					@Override
					public boolean onTouch(View view, MotionEvent event) {	
						
						Button button = (Button) view;
						
						if (event.getAction()==MotionEvent.ACTION_DOWN) {														
							
							lastX = event.getX();	
							
						} else if (event.getAction()==MotionEvent.ACTION_UP) {
							
				        	float currentX = event.getX();
				        	
				        	if (Math.abs(currentX-lastX)>20) { // a big swipe was done			        	
				        		if (lastX < currentX) { 
				        			switchMonth(-1);
				        		} else if (lastX > currentX) {                 
				        			switchMonth(1);
				        		}
				        	} else { // the swipe was small, probably trying to click a button											
							
				        		int date = Integer.parseInt(button.getText().toString());
							
				        		Intent i = new Intent(getApplicationContext(),MinistryDetailsActivity.class);
				        		i.putExtra("date",date);
				        		i.putExtra("month",month);
				        		i.putExtra("year",year);					    
				        		startActivity(i);
				        	}
							
						}
						
						return false;
					}
					
				});
				
			}
		}
		
		// Update weekday labels
		if (Global.firstDayOfWeek==0) {
			dayLabels[0].setText(Global.res.getText(R.string.label_sun));
			dayLabels[1].setText(Global.res.getText(R.string.label_mon));
			dayLabels[2].setText(Global.res.getText(R.string.label_tue));
			dayLabels[3].setText(Global.res.getText(R.string.label_wed));
			dayLabels[4].setText(Global.res.getText(R.string.label_thu));
			dayLabels[5].setText(Global.res.getText(R.string.label_fri));
			dayLabels[6].setText(Global.res.getText(R.string.label_sat));
		} else {
			dayLabels[0].setText(Global.res.getText(R.string.label_mon));
			dayLabels[1].setText(Global.res.getText(R.string.label_tue));
			dayLabels[2].setText(Global.res.getText(R.string.label_wed));
			dayLabels[3].setText(Global.res.getText(R.string.label_thu));
			dayLabels[4].setText(Global.res.getText(R.string.label_fri));
			dayLabels[5].setText(Global.res.getText(R.string.label_sat));
			dayLabels[6].setText(Global.res.getText(R.string.label_sun));
		}
		
		for (int i=0; i<6; i++) {
			for (int j=0; j<7; j++) {
				calendarView[activeCalendarView].calendarDays[i][j].setVisibility(View.INVISIBLE);
				calendarView[activeCalendarView].calendarDays[i][j].getBackground().clearColorFilter();
				calendarView[activeCalendarView].calendarDays[i][j].setTextColor(Color.BLACK);
			}
		}
		
		// Populate calendar buttons with dates
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month);
		cal.set(Calendar.DAY_OF_MONTH, 1);
		int daysInMonth = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
		int row=0;
		int col = cal.get(Calendar.DAY_OF_WEEK)-1;
		if (Global.firstDayOfWeek==1)
			col--;
		if (col<0)
			col=6;
		int i=1;
		while (i<=daysInMonth) {
			calendarView[activeCalendarView].calendarDays[row][col].setVisibility(View.VISIBLE);
			calendarView[activeCalendarView].calendarDays[row][col].setText(""+i);
			calendarView[activeCalendarView].calendarDays[row][col].setTypeface(Typeface.DEFAULT);
			calendarView[activeCalendarView].calendarDays[row][col].setTextSize(13);
			
			Calendar today = Calendar.getInstance();
			
			// Highlight today's date
			if (i==today.get(Calendar.DAY_OF_MONTH) && today.get(Calendar.MONTH)==month && today.get(Calendar.YEAR)==year)
				calendarView[activeCalendarView].calendarDays[row][col].getBackground().setColorFilter(0xFFFFD700, PorterDuff.Mode.MULTIPLY);

			i++;
			col++;
			if (col>6) {
				col=0;
				row++;
			}
		}
		
		// Highlight days that have some ministry data recorded
		Cursor cursor;		
		cursor = Database.select("SELECT date FROM ministry WHERE year="+year+" AND month="+month+" AND (hours>0 OR minutes>0 OR chours>0 OR cminutes>0 "+
								 "OR magazines>0 OR brochures>0 OR books>0 OR returncalls>0 OR comments!='')");
		while (cursor.moveToNext()) {
			int d = cursor.getInt(cursor.getColumnIndex("date"));
			for (int r=0; r<6; r++)
				for (int c=0; c<7; c++)
					if (calendarView[activeCalendarView].calendarDays[r][c].getText().equals(""+d) && calendarView[activeCalendarView].calendarDays[r][c].getVisibility()==View.VISIBLE) {
						calendarView[activeCalendarView].calendarDays[r][c].setTypeface(null, Typeface.BOLD);
						calendarView[activeCalendarView].calendarDays[r][c].setTextSize(16);
						calendarView[activeCalendarView].calendarDays[r][c].setTextColor(Color.parseColor("#ffaa00"));						
						break;
					}
		}
		cursor.close();		
		
		// Highlight days that have calls to persons recorded
		cursor = Database.select("SELECT date FROM calls WHERE year="+year+" AND month="+month+" AND personid<>0 AND timestamp<>"+Global.TIMESTAMP_DELETED);
		while (cursor.moveToNext()) {
			int d = cursor.getInt(cursor.getColumnIndex("date"));
			for (int r=0; r<6; r++)
				for (int c=0; c<7; c++)
					if (calendarView[activeCalendarView].calendarDays[r][c].getText().equals(""+d) && calendarView[activeCalendarView].calendarDays[r][c].getVisibility()==View.VISIBLE) {
						calendarView[activeCalendarView].calendarDays[r][c].setTypeface(null, Typeface.BOLD);
						calendarView[activeCalendarView].calendarDays[r][c].setTextSize(16);
						calendarView[activeCalendarView].calendarDays[r][c].setTextColor(Color.parseColor("#ffaa00"));						
						break;
					}
		}
		cursor.close();	
		
    }
    
    @Override
    public void onResume() {
    	super.onResume();
    	
        loadMonth();
        
        //Update the timer button depending on whether it is started or not
        Cursor c = Database.select("SELECT value FROM settings WHERE name='timerstart'");
        c.moveToNext();
        if (c.getInt(c.getColumnIndex("value"))==0)
        	timerButton.setBackgroundDrawable(Global.res.getDrawable(R.drawable.timer_button));
        else {
        	timerButton.setBackgroundResource(R.drawable.timer_animation);
        	AnimationDrawable frameAnimation = (AnimationDrawable) timerButton.getBackground();
        	frameAnimation.start();
        }
        
    }    
	
	private void switchMonth(int direction) {		
		
		if (direction<0) {
			viewFlipper.setInAnimation(this, R.anim.move_in_from_left);    
			viewFlipper.setOutAnimation(this, R.anim.move_out_to_right);
		} else {
        	viewFlipper.setInAnimation(this, R.anim.move_in_from_right);
            viewFlipper.setOutAnimation(this, R.anim.move_out_to_left);
		}
		
		activeCalendarView = (activeCalendarView + 1) % 2;			
		
		int year = calendar.get(Calendar.YEAR);
		int month = calendar.get(Calendar.MONTH) + direction;
		
		if (month<0) {
			month=11; year--;
		}
		
		if (month>11) {
			month=0; year++;
		}
		
		calendar.set(Calendar.YEAR, year);
		calendar.set(Calendar.MONTH, month);							
		
		loadMonth();
		
        // Show the next screen
        viewFlipper.showNext();
		
	}		
	
	@Override
	public void onDestroy() {
		super.onDestroy();
		Log.i(Global.TAG,"Shutting down MyService...");
		Global.saveSettings();
		Database.closeConnection();		
	}	
	
    public boolean onTouchEvent(MotionEvent touchevent) {
    	if (touchevent.getAction()==MotionEvent.ACTION_DOWN) {
    		lastX = touchevent.getX();            	
        } else if (touchevent.getAction()==MotionEvent.ACTION_UP) {        	
        	float currentX = touchevent.getX();                 
            if (lastX < currentX) { 
            	switchMonth(-1);
            } else if (lastX > currentX) {                 
            	switchMonth(1);
            }                        
        }        
        return true;
    }	
    
    /**
     * Creates the "MyService" folder on the SD card, if available
     */
    private void createMyServiceFolder() {    	    	
    	
    	if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
    		return;
    	
    	File dir = new File(Environment.getExternalStorageDirectory().getPath()+"/MyService");
    	
    	if (dir.exists()) {
    		Global.folderMyServiceExists = true;
    		return;
    	}
    	
    	if (dir.mkdir()) {
    		Log.i(Global.TAG,"'MyService' folder created on the SD card.");
    		Global.folderMyServiceExists = true;
    	}
    	
    }
    
}